#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

#include "config.h"
#include "client_handler.h"

pthread_t new_tid;

int main(int argc, char *argv[])
{
    int                ret, opt;
    int                sockfd;
    int                clientfd;
    int                length;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    
    /* ====== 01.创建TCP，监听 NanoPi 的连接 ====== */
    /* 流式套接字 */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    /* 判断文件描述符是否创建成功 */
    if (sockfd == -1)
    {
        perror("socket create failed");
        exit(1);
    }

    /* 地址复用 */
    opt = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    /* 绑定 */
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(ALI_PORT);
    server_addr.sin_addr.s_addr = inet_addr(ALI_INET_ADDR);

    ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));

    /* 判断套接字是否绑定成功 */
    if (ret == -1)
    {
        perror("tcp bind failed");
        exit(1);
    }

    /* 监听 */
    ret = listen(sockfd, 10);

    /* 判断监听是否绑定成功 */
    if (ret == -1)
    {
        perror("listen nano_sockfd failed\n");
        exit(1);
    }

    /* 管理链表初始化 */
    mng_list_init();

    /* 视频数据结构体初始化 */
    video_data_t_init();

    printf("start listen......\n");

    /* 等待客户端 (APP / NanoPi) TCP连接 */

    while(1)
    {
        length = sizeof(client_addr);
        memset(&client_addr, 0, sizeof(client_addr));
        clientfd = accept(sockfd, (struct sockaddr *)&client_addr, (socklen_t *)&length);

        printf("new client -%d- is connected\n", clientfd);

        /* 创建新线程去处理连接请求 */
        ret = pthread_create(&new_tid, NULL, client_connect_handler, &clientfd);

        /* 判断线程是否创建成功 */
        if (ret != 0)
        {
            perror("create client handler thread failed");
            exit(1);
        }

        /* 主线程和子线程分离 */
        pthread_detach(new_tid);
    }
}